"use strict";
import React, { useState, useEffect, useRef } from "react";
import layoutBox from "@/hook/layoutBox";
import Zoom from "./zoom";
import Panel from "./panel";
import translationsCN from "./plugins/translate/zh";
import customTranslate from "./plugins/translate/customTranslate";
import BpmnModeler from "bpmn-js/lib/Modeler";
// 模拟流转流程
import tokenSimulation from "bpmn-js-token-simulation";
// 标签解析构建器
// import bpmnPropertiesProvider from "bpmn-js-properties-panel/lib/provider/bpmn";

// 标签解析 Moddle
import camundaModdleDescriptor from "./plugins/descriptor/camundaDescriptor.json";
import activitiModdleDescriptor from "./plugins/descriptor/activitiDescriptor.json";
import flowableModdleDescriptor from "./plugins/descriptor/flowableDescriptor.json";
// 标签解析 Extension
import camundaModdleExtension from "./plugins/extension-moddle/camunda";
import activitiModdleExtension from "./plugins/extension-moddle/activiti";
import flowableModdleExtension from "./plugins/extension-moddle/flowable";
import DefaultEmptyXML from "./plugins/defaultEmpty";

// import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
// import propertiesPanelModule from "bpmn-js-properties-panel";

// 自定义元素选中时的弹出菜单（修改 默认任务 为 用户任务）
import CustomContentPadProvider from "./plugins/content-pad";
// 自定义左侧菜单（修改 默认任务 为 用户任务）
import CustomPaletteProvider from "./plugins/palette";
// 小地图
import minimapModule from "diagram-js-minimap";
import "bpmn-js/dist/assets/diagram-js.css"; // 左边工具栏以及编辑节点的样式
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
import "bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css"; // 右边工具栏样式
import styles from "./index.less";

// import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
// import propertiesPanelModule from "bpmn-js-properties-panel";
// 标签解析构建器
// import bpmnPropertiesProvider from "bpmn-js-properties-panel/lib/provider/bpmn";
/*
 * 组件注释
 * create by wuqiong
 * creation time 2022/03/10
 * bpmn流程图
 * */

const Index = props => {
  const {
    keyboard = true,
    options = {
      taskResizingEnabled: true,
      eventResizingEnabled: true,
    },
    onlyCustomizeAddi = false,
    translations,
    simulation = true,
    moddleExtension,
    onlyCustomizeModdle = false,
  } = props;

  const [controlForm, setControlForm] = useState({
    processId: "",
    processName: "",
    labelEditing: false,
    labelVisible: false,
    prefix: "flowable",
    events: ["element.click", "element.contextmenu"],
    additionalModel: [
      CustomContentPadProvider,
      CustomPaletteProvider,
      minimapModule,
    ],
  });

  const [bpmnModeler, setBpmnModeler] = useState();

  const save = async e => {
    const { err, xml } = await bpmnModeler.saveXML();
    console.log(err, xml);
    /*  try {
       // 按需要类型创建文件并下载
       if (type === "xml" || type === "bpmn") {
         const { err, xml } = await bpmnModeler.saveXML();
         // 读取异常时抛出异常
         if (err) {
           console.error(`[Process Designer Warn ]: ${err.message || err}`);
         }
         let { href, filename } = setEncoded(type.toUpperCase(), name, xml);
         downloadFunc(href, filename);
       } else {
         const { err, svg } = await bpmnModeler.saveSVG();
         // 读取异常时抛出异常
         if (err) {
           return console.error(err);
         }
         let { href, filename } = setEncoded("SVG", name, svg);
         downloadFunc(href, filename);
       }
     } catch (e) {
       console.error(`[Process Designer Warn ]: ${e.message || e}`);
     } */
  };

  const additionalModules = () => {
    const Modules = [];
    // 仅保留用户自定义扩展模块
    if (onlyCustomizeAddi) {
      if (
        Object.prototype.toString.call(controlForm.additionalModel) ===
        "[object Array]"
      ) {
        return controlForm.additionalModel || [];
      }
      return [controlForm.additionalModel];
    }

    // 插入用户自定义扩展模块
    if (
      Object.prototype.toString.call(controlForm.additionalModel) ===
      "[object Array]"
    ) {
      Modules.push(...controlForm.additionalModel);
    } else {
      controlForm.additionalModel && Modules.push(controlForm.additionalModel);
    }

    // 翻译模块
    const TranslateModule = {
      translate: ["value", customTranslate(translations || translationsCN)],
    };
    Modules.push(TranslateModule);

    // 模拟流转模块
    if (simulation) {
      Modules.push(tokenSimulation);
    }

    // 根据需要的流程类型设置扩展元素构建模块
    // if (prefix === "bpmn") {
    //   Modules.push(bpmnModdleExtension);
    // }
    if (controlForm.prefix === "camunda") {
      Modules.push(camundaModdleExtension);
    }
    if (controlForm.prefix === "flowable") {
      Modules.push(flowableModdleExtension);
    }
    if (controlForm.prefix === "activiti") {
      Modules.push(activitiModdleExtension);
    }

    return Modules;
  };
  const moddleExtensions = () => {
    const Extensions = {};
    // 仅使用用户自定义模块
    if (onlyCustomizeModdle) {
      return moddleExtension || null;
    }

    // 插入用户自定义模块
    if (moddleExtension) {
      for (let key in moddleExtension) {
        Extensions[key] = moddleExtension[key];
      }
    }

    // 根据需要的 "流程类型" 设置 对应的解析文件
    if (controlForm.prefix === "activiti") {
      Extensions.activiti = activitiModdleDescriptor;
    }

    if (controlForm.prefix === "flowable") {
      Extensions.flowable = flowableModdleDescriptor;
    }
    if (controlForm.prefix === "camunda") {
      Extensions.camunda = camundaModdleDescriptor;
    }
    return Extensions;
  };

  const createNewDiagram = async (xml, bpmn) => {
    // 将字符串转换成图显示出来
    let newId = controlForm.processId || `Process_${new Date().getTime()}`;
    let newName = controlForm.processName || `业务流程_${new Date().getTime()}`;
    let xmlString = xml || DefaultEmptyXML(newId, newName, controlForm.prefix);

    try {
      let { warnings } = await (bpmn || bpmnModeler).importXML(xmlString);
      (bpmn || bpmnModeler).get("canvas").zoom("fit-viewport", "auto");
      if (warnings && warnings.length) {
        warnings.forEach(warn => console.warn(warn));
      }
    } catch (e) {
      console.error(`[Process Designer Warn]: ${e?.message || e}`);
    }
  };
  const initModeler = modeler => {
    setTimeout(() => {
      const canvas = modeler.get("canvas");
      const rootElement = canvas.getRootElement();
      // Log.prettyPrimary("Process Id:", rootElement.id);
      // Log.prettyPrimary("Process Name:", rootElement.businessObject.name);
    }, 10);
  };

  useEffect(() => {
    /* const bpmnModeler = new BpmnModeler({
      container: document.getElementById("canvas"),
      height: "100%",
      //添加控制板
      propertiesPanel: {
        parent: "#attrs-panel",
      },
      moddleExtensions: {
        camunda: camundaModdleDescriptor,
      },
      additionalModules: [
        propertiesPanelModule,
        propertiesProviderModule,
        { translate: ["value", customTranslate(translationsCN)] },
        { zoomScroll: ["value", ""] },
      ],
      // 或者window，注意与外部表单的键盘监听事件是否冲突
      keyboard: { bindTo: document, },
    }); */

    const bpmnModeler = new BpmnModeler({
      container: document.getElementById("canvas"),
      keyboard: keyboard ? { bindTo: document } : null,
      additionalModules: additionalModules(),
      moddleExtensions: moddleExtensions(),
      ...options,
    });
    setBpmnModeler(bpmnModeler);
    createNewDiagram(null, bpmnModeler);
    initModeler(bpmnModeler);
    return () => {
      if (bpmnModeler) bpmnModeler.destroy();
    };
  }, []);

  return (
    <div className={styles.bpmn}>
      {bpmnModeler ? (
        <Zoom
          bpmnModeler={bpmnModeler}
          simulation={simulation}
          createNewDiagram={createNewDiagram}
          events={controlForm.events}
        />
      ) : null}

      <div className={styles.bpmn_content} id={"attrs-panel"}>
        <div id="canvas" className={styles.container} />

        {bpmnModeler && (
          <Panel
            width={480}
            bpmnModeler={bpmnModeler}
            prefix={controlForm.prefix}
          />
        )}
      </div>
    </div>
  );
};
export default layoutBox(Index);
